import NavBar from '@/components/NavBar';
import { DatePicker, Dialog, List, Popup, Toast } from 'antd-mobile';
import { useEffect, useState, useRef } from 'react';
import styles from './index.module.scss';
import { useDispatch } from 'react-redux';
import {
  getUserProfileAction,
  updatePhotoAction,
  updateProfileAction,
} from '@/store/action/user';
import { useAppSelector } from '@/store';
import { ProfileType } from '@/store/reducers/user';
import Input from '@/components/Input';
import Textarea from '@/components/TextArea';
import dayjs from 'dayjs';
import { clearToken } from '@/utils/storage';
import history from '@/utils/history';

export default function ProfileEdit() {
  // 18.2.1 声明控制type的类型
  type EditType = 'photo' | 'gender' | 'intro' | 'name';
  // 18.2.2 声明初始值
  const [editType, setEditType] = useState('' as EditType);

  // 2. 声明头像state控制弹出层显示
  const [visible, setVisible] = useState(false);

  //18.4.1 声明昵称state控制弹出层显示
  const [rightVisible, setRightVisible] = useState(false);

  //18.6.1 声明受控组件
  const [name, setName] = useState('');

  //18.9.1 声明 intro
  const [intro, setIntro] = useState('');

  //18.10.1  声明 生日默认值
  const [birthVisible, setBirthVisible] = useState(false);

  //18.2.3 点击事件 传类型 控制弹出窗的内容 显示
  const handleShowEdit = (editType: EditType) => {
    setEditType(editType);
    setVisible(true);
  };
  //18.5.3 点击事件 传类型 控制弹出窗的内容 显示 name 和 intro
  const handleRightShowEdit = (editType: EditType) => {
    setEditType(editType);
    setRightVisible(true);
  };

  //测试 可以合在一起写 18.2.3 和 18.5.3
  // const handleShowEdit = (editType: EditType) => {
  //   if (editType === 'photo' || editType ==='gender') {
  //     setEditType(editType);
  //     setVisible(true);
  //   } else if (editType === 'intro' ||editType === 'name') {
  //     setEditType(editType);
  //     setRightVisible(true);
  //   }
  // };

  // 17.2.3 触发dispatch 发送请求
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(getUserProfileAction());
  }, [dispatch]);

  //17.2.6 用户资料取数据
  const { profile } = useAppSelector((state) => state.user);

  // 18.7.1同步初始值
  useEffect(() => {
    setName(profile.name || '');
  }, [profile.name]);

  //18.9.4 同步初始值  数据为null 时更新value 会导致报错
  useEffect(() => {
    setIntro(profile.intro || '');
  }, [profile.intro]);

  // 17.3.1创建ref 保存上传的按钮
  const uploadRef = useRef<HTMLInputElement>(null);

  const handleUpload = () => {
    // 17.3.3 onclick 事件 触发上传按钮的click事件
    uploadRef.current?.click();
  };

  //17.3.5 接收
  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
    if (e.target.files) {
      console.log('e.target.files[0]  ----->  ', e.target.files[0]);
      //17.4.3 声明formdata  后台需要formdata
      const formData = new FormData();
      formData.append('photo', e.target.files[0]);
      //17.4.4 调用更新头像action
      dispatch(updatePhotoAction(formData));
      //18.1.4 关闭弹出层
      // 4. 关闭弹框 提示用户
      Toast.show({ content: '更新成功' });
      setVisible(false);
    }
  };
  //18.3.4 触发调用异步action  传值
  const handleUpdateProfile = async (data: Partial<ProfileType>) => {
    await dispatch(updateProfileAction(data));
    // 18.3.6 更新页面 关闭弹窗
    Toast.show({ content: '更新成功' });
    setVisible(false);
    //18.7.3 无论是否打开 都关闭弹窗
    setRightVisible(false);
    ////18.10.3 无论是否打开 都关闭日期弹窗
    setBirthVisible(false);
  };

  //18.8.1 按返回键 关闭弹窗 并且再次进来的时候 把redu的数据重新传回去
  const handleBack = () => {
    setRightVisible(false);
    editType === 'name' && setName(profile.name);
    //18.9.6  返回清空
    editType === 'intro' && setIntro(profile.intro);
  };

  // 18.8.2 按下确定键 提交名称
  const handleKeyDown = (
    e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    // console.log(107, e.key);

    if (e.key === 'Enter') {
      editType === 'name' && handleUpdateProfile({ name });
      //18.9.5 按下确定键 提交简介
      editType === 'intro' && handleUpdateProfile({ intro });
    }
  };

  // 18.11.2 退出登录
  const handleLogout = () => {
    Dialog.confirm({
      title: '温情提示',
      content: '你确定退出吗?',
      onConfirm: () => {
        //清除token
        clearToken();
        // 跳转页面
        history.push('/login');
        // 提示用户
        Toast.show({ content: '退出成功' });
      },
    });
  };

  return (
    <div className={styles.root}>
      <div className="content">
        {/* 顶部导航栏 */}
        <NavBar>个人资料</NavBar>
        <div className="wrapper">
          {/* 列表一：显示头像、昵称、简介 */}
          <List className="profile-list">
            <List.Item
              arrow
              extra={<img className="avatar" src={profile.photo} alt="" />}
              onClick={() => handleShowEdit('photo')}
            >
              头像
            </List.Item>

            <List.Item
              arrow
              extra={profile.name}
              //18.4.2 点击显示弹窗
              onClick={() => handleRightShowEdit('name')}
            >
              昵称
            </List.Item>

            <List.Item
              arrow
              extra={<span className="intro">{profile.intro}</span>}
              // 18.5.2  点击显示弹窗
              onClick={() => handleRightShowEdit('intro')}
            >
              简介
            </List.Item>

            <List.Item
              arrow
              extra={profile.gender === 0 ? '男' : '女'}
              onClick={() => handleShowEdit('gender')}
            >
              性别
            </List.Item>
            <List.Item
              arrow
              extra={profile.birthday}
              onClick={() => setBirthVisible(true)}
            >
              生日
            </List.Item>
          </List>

          {/* 文件选择框，用于头像图片的上传 */}
          {/* 17.3.2 ref绑定上传按钮 */}
          {/* 17.3.4 绑定onchange 获取上传的文件信息 */}
          <input
            className="avatar-upload"
            type="file"
            ref={uploadRef}
            onChange={(e) => handleFileChange(e)}
          />
        </div>
        {/* 底部栏：退出登录按钮 */}
        <div className="logout">
          {/* 18.11.1 退出登录 绑定点击事件  */}
          <button className="btn" onClick={handleLogout}>
            退出登录
          </button>
        </div>{' '}
        {/* 1. 设置头像弹出层组件, cv机构与样式 */}
        <Popup
          visible={visible}
          position="bottom"
          bodyClassName="popup-bottom-list"
          // 4. 设置关闭弹出层
          onMaskClick={() => setVisible(false)}
        >
          {/* //18.2.4  根据类型显示 */}

          {editType === 'photo' && (
            <div>
              <div className="list-item" onClick={handleUpload}>
                拍照
              </div>
              <div className="list-item">本地选择</div>
              {/* // 4. 设置关闭弹出层 */}
              <div className="list-item" onClick={() => setVisible(false)}>
                取消
              </div>
            </div>
          )}
          {editType === 'gender' && (
            <div>
              {/* 18.3.3 点击事件触发action */}
              <div
                className="list-item"
                onClick={() => handleUpdateProfile({ gender: 0 })}
              >
                男
              </div>
              <div
                className="list-item"
                onClick={() => handleUpdateProfile({ gender: 1 })}
              >
                女
              </div>
              <div className="list-item" onClick={() => setVisible(false)}>
                取消
              </div>
            </div>
          )}
        </Popup>
        {/* 右侧弹出层 */}
        <Popup
          visible={rightVisible}
          position="right"
          bodyClassName="popup-right"
          // 18.6.4 卸载 这样才能在隐藏时 ,再次进来能自动聚焦
          destroyOnClose
        >
          {/* 18.5.1 改造三元 变成 && 运算符 */}
          {editType === 'name' && (
            <>
              <NavBar
                //18.4.3 点击返回 关闭弹窗
                onBack={handleBack}
                //18.7.2   点击触发 异步action
                right={
                  <span
                    className="submit-btn"
                    onClick={() => handleUpdateProfile({ name })}
                  >
                    提交
                  </span>
                }
              >
                编辑用户信息
              </NavBar>
              <div className="edit-content">
                <h3 className="edit-title">编辑昵称</h3>
                <Input
                  className="edit-input"
                  // 18.6.2 受控组件绑定
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                  // 18.6.3 自动聚焦  popup组件要开启destroyOnClose 18.6.4 卸载 这样才能在隐藏时 ,再次进来能自动聚焦
                  autoFocus
                  //  18.8.2 按下确定事件
                  onKeyDown={(e) => handleKeyDown(e)}
                />
              </div>
            </>
          )}
          {editType === 'intro' && (
            <>
              <NavBar
                //18.4.3 点击返回 关闭弹窗
                onBack={handleBack}
                right={
                  <span
                    className="submit-btn"
                    // 18.9.3 提交
                    onClick={() => handleUpdateProfile({ intro })}
                  >
                    提交
                  </span>
                }
              >
                编辑简介
              </NavBar>
              <Textarea
                // 18.9.2 受控组件绑定
                value={intro}
                onChange={(e) => setIntro(e.target.value)}
                onKeyDown={(e) => handleKeyDown(e)}
              />
            </>
          )}
        </Popup>
        {/* 生日 //18.10.2 一堆对日期的操作*/}
        <DatePicker
          //标题
          title="选择生日"
          //弹窗值
          visible={birthVisible}
          //最大的日期选择
          max={new Date()}
          //最小的日期选择
          min={new Date('1900-01-01')}
          //控制默认日期
          defaultValue={new Date()}
          value={new Date(profile.birthday)}
          //选中日期 按确定
          onConfirm={(val) =>
            handleUpdateProfile({ birthday: dayjs(val).format('YYYY-MM-DD') })
          }
          //按取消
          onClose={() => setBirthVisible(false)}
        ></DatePicker>
      </div>
    </div>
  );
}
